using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public interface IDataFactory
{
    int ID { get; }
    object Get(int index);
    void QueryData();
}

public enum DataModelType
{
    List,
    Dictionary,
}

public abstract class DataModelSingleton<T,M,F,KEY> : MonoBehaviour,IDataFactory where M : class, IDataModel<M, F, KEY>, new() where F : class where T : DataModelSingleton<T, M, F, KEY>
{
    public static T Instance { get; private set; }
    protected static System.Func<IDataModelCenter<M, F, KEY>> AsList(System.Func<M> creator, int eventId, int capacity = 32, int poolCapacity = 32)
    {
        return () => new ListCtrl<M, F, KEY>(creator, eventId, capacity, poolCapacity);
    }

    protected static System.Func<IDataModelCenter<M, F, KEY>> AsDictionary(System.Func<M> creator, int eventId, int capacity = 32, int poolCapacity = 32)
    {
        return () => new DicCtrl<M, F, KEY>(creator, eventId, capacity, poolCapacity);
    }

    public abstract int ID { get; }

    protected abstract System.Func<IDataModelCenter<M, F, KEY>> DataModelCreator { get; }

    IDataModelCenter<M, F, KEY> datas;

    protected virtual void OnAwake()
    {

    }

    void Awake()
    {
        Instance = this as T;
        datas = DataModelCreator();
        EventDispatchManager.Instance.SendEvent<IDataFactory>(CtrlEventID.EVENT_CONNECT_DATA_CENTER, this);
        OnAwake();
    }

    void OnDestroy()
    {
        Instance = null;
    }

    public void Add(F p)
    {
        datas.Add(p);
    }

    public void Clear()
    {
        datas.Clear();
    }

    public bool Contains(F p)
    {
        return datas.Contains(p);
    }

    public void Initialze(IEnumerable<F> collections)
    {
        datas.Initialze(collections);
    }

    public bool Remove(KEY Key)
    {
        return datas.Remove(Key);
    }

    public void Modify(F p)
    {
        datas.Modify(p);
    }

    public object Get(int index)
    {
        return this.datas.Get(index);
    }

    public void QueryData()
    {
        EventDispatchManager.Instance.SendEvent(CtrlEventID.EVENT_DATA_FACTORY_DATA_CHANGED,ID,datas.Count);
    }
}
